#include <qapplication.h>
#include "window.moc"
#include "glwidget.h"
#include "ucdinputfile.h"
#include "visFlowGuided.h"

using namespace visualization;
using namespace std;

class glW: public GLWidget
{
public:
	glW(QWidget *parent = 0) 
	     : GLWidget(parent), forward(NULL), backward(NULL)
	{}
	~glW()
	{
		delete forward;;
		delete backward;
	}
private:
	Model t;
	intgResults *forward, *backward;
	// This is used to display the saddle point on the screen.
	vector<saddlePoint> saddle;

public:
	GLuint makeObject();
};

class win : public Window
{
public:
	win(glW *glwidget)
		: Window(glwidget)
	{}
	~win(){}
};

int main(int argc, char *argv[])
{
	if(argc < 2)
	{
		cerr << "Input a data file please..." << endl;
		return 0;
	}

  QApplication app(argc, argv);
	glW *glw = new glW();
	glw->setFileName(argv[1]);
  win window(glw);
	window.generateWindow();
  window.show();
  app.exec();
	return 0;
}

GLuint glW::makeObject()
{
	GLuint list = glGenLists(1);
	glNewList(list, GL_COMPILE);

	UCDInputFile file(filename);
	file.FGetModel(t);	
	t.buildKDTree();

	visFlowGuided fg(&t);
	fg.setRdAndSmpRate(1, 4);
	fg.setZero(1e-6);
	fg.setDelt(1e-3);
	fg.setDiavationFromSaddle(1);
	fg.setNeighbourNum(10);
	fg.setDisError(4);
	fg.determineCriticalPoint();
	fg.preProcessSaddles();
	fg.integrateCurves(forward, backward);
	size_t n = 0;
	saddle = fg.getSaddles(n);
	Point *fs, *bs;
	fg.getSources(fs, bs);
	
	fg.groupCriticalPoints();
	fg.initializeTemplates();
	fg.makeSources();
	vector<Point> templateSources = fg.getTemplateSources();
	vector<criticalPoint> criticalPoints = fg.getCriticalPoints();
	intgResults *intgCurves = fg.integrate();

	double xmin, xmax, ymin, ymax, zmin, zmax;
	t.getBound(xmin, xmax, ymin, ymax, zmin, zmax);
	double c[3] = 
	{
		(xmin+xmax)/2,
		(ymin+ymax)/2,
		(zmin+zmax)/2
	};
	double scale = 70;
	glBegin(GL_LINES);
	drawFramework(xmin-c[0], xmax-c[0], ymin-c[1], ymax-c[1], zmin-c[2], zmax-c[2], scale);
	glEnd();

//	glPointSize(4);
//	glColor3f(1.0, 0.0, 0.0);
//	glBegin(GL_POINTS);		
//		for(size_t i = 0; i < saddle.size(); i++)
//		{
//			glVertex3f( (saddle[i].x-c[0])/scale, (saddle[i].y-c[1])/scale, 0);
//		}
//	glEnd();
//
//	glColor3f(0.1, 1.0, 0.4);
//	for(size_t i = 0; i < forward->size(); i++)
//	{
//		glBegin(GL_LINE_STRIP);		
//			for(size_t j = 0; j < (*forward)[i].size(); j++)
//				glVertex3f(((*forward)[i][j].getX()-c[0])/scale, ((*forward)[i][j].getY()-c[1])/scale, 0);
//		glEnd();
//	}
//	for(size_t i = 0; i < backward->size(); i++)
//	{
//		glBegin(GL_LINE_STRIP);		
//			for(size_t j = 0; j < (*backward)[i].size(); j++)
//				glVertex3f(((*backward)[i][j].getX()-c[0])/scale, ((*backward)[i][j].getY()-c[1])/scale, 0);
//		glEnd();
//	}
//
//	for(size_t i = 0; i < n; i++)
//	{
//	
//			glBegin(GL_LINE_STRIP);
//				for(size_t j = 0; j < 2; j++)	
//				{	
//					glVertex3f((fs[2*i+j].getX()-c[0])/scale, (fs[2*i+j].getY()-c[1])/scale, 0);
//				}
//			glEnd();	
//			glBegin(GL_LINE_STRIP);
//				for(size_t j = 0; j < 2; j++) 
//				{	
//					glVertex3f((bs[2*i+j].getX()-c[0])/scale, (bs[2*i+j].getY()-c[1])/scale, 0);
//				}
//			glEnd();
//	}

// For flow guided streamline placement...
	glBegin(GL_POINTS);
	for(size_t i = 0; i < templateSources.size(); i++)
	{
		glVertex3f( (templateSources[i].getX()-c[0])/scale, 
								(templateSources[i].getY()-c[1])/scale, 
								(templateSources[i].getZ()-c[2])/scale 
							);
	}
	glEnd();

	glBegin(GL_POINTS);
	for(size_t i = 0; i < criticalPoints.size(); i++)
	{
		glVertex3f( (criticalPoints[i].position.getX()-c[0])/scale, 
								(criticalPoints[i].position.getY()-c[1])/scale, 
								(criticalPoints[i].position.getZ()-c[2])/scale 
							);
	}
	glEnd();

	for(size_t i = 0; i < (*intgCurves).size(); i++)
	{
		glBegin(GL_LINE_STRIP);
		for(size_t j = 0; j < (*intgCurves)[i].size(); j++)
		{
			glVertex3f( ((*intgCurves)[i][j].getX()-c[0])/scale, 
									((*intgCurves)[i][j].getY()-c[1])/scale, 
								  ((*intgCurves)[i][j].getZ()-c[2])/scale);
		}
		glEnd();
	}
	
	delete []fs;
	delete []bs;
	delete intgCurves;

	glEndList();
	return list;
}

